package com.leesche.zcsp.node.web.service.impl;

import com.leesche.zcsp.node.utils.web.messge.WebResult;
import com.leesche.zcsp.node.web.constants.Constants;
import com.leesche.zcsp.node.web.dao.SysModuleDao;
import com.leesche.zcsp.node.web.model.SysModule;
import com.leesche.zcsp.node.web.model.SysModuleCriteria;
import com.leesche.zcsp.node.web.model.SysRoleModule;
import com.leesche.zcsp.node.web.service.SysModuleService;
import com.leesche.zcsp.node.web.service.SysRoleModuleService;
import com.leesche.zcsp.node.web.service.impl.data.read.QuerySysModuleCondition;
import com.leesche.zcsp.node.web.service.impl.data.read.QuerySysRoleModuleCondition;
import com.leesche.zcsp.node.web.service.impl.data.read.SysModuleDto;
import com.leesche.zcsp.node.web.service.impl.data.read.SysRoleModuleDto;
import com.leesche.zcsp.node.web.service.privilege.PrivilegeService;
import com.leesche.zcsp.node.web.vo.Module;
import com.leesche.zcsp.node.web.vo.v2.Menu;
import com.leesche.zcsp.node.web.vo.Principal;
import com.leesche.zcsp.node.web.vo.Privilege;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author 陈立勇
 * @version V1.0
 * @Title: SysModuleServiceImpl.java
 * @Description: TODO(调度SysModuleDao的数据表操作)
 * @date 2016年9月13日 下午4:08:58
 */
@Service
@Transactional
public class SysModuleServiceImpl
        extends
        BaseServiceImpl<SysModule, SysModuleCriteria, SysModuleDto, QuerySysModuleCondition, Long>
        implements SysModuleService {

    private static Logger log = Logger.getLogger(SysModuleServiceImpl.class.getName());

    @Autowired
    private SysModuleDao sysModuleDao;

    @Autowired
    private PrivilegeService privilegeService;

    @Autowired
    private SysRoleModuleService sysRoleModuleService;

    @Autowired
    public void setBaseDao(SysModuleDao sysModuleDao) {
        super.setBaseDao(sysModuleDao);
    }

    /**
     * @return PC端系统权限树
     * @Title: findSysModuleTrees()
     * @Description: TODO(获取PC端系统权限树)
     * @author Jerry
     * @date 2016-10-17 11:02:36
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<Menu> findSysModuleTrees() {

        Principal principal = privilegeService.getCurrentPrincipal();
        if (principal == null) {
            return null;
        }
        //List<Privilege> privileges = new ArrayList<Privilege>();
        Map<Long, Privilege> userModules = new HashMap<Long, Privilege>();
        for (Long moduleid : principal.getModuleIds()) {
            Privilege pg = privilegeService.getWebPrivileges().get(moduleid);
            if (pg != null) {
                //privileges.add(pg);
                userModules.put(moduleid, pg);
            }
        }
        return menusAppend(userModules, 0L, true);
    }

    @Override
    public Map<String, Object> getRoleModules(Long usergroupid) throws Exception {
        /*已使用的权限*/
        Principal principal = privilegeService.getCurrentPrincipal();
        QuerySysRoleModuleCondition condition = new QuerySysRoleModuleCondition();
        condition.setRoleid(usergroupid);
        condition.setAdminid(principal.getUserid());
        List<SysRoleModuleDto> usedRoleModules = sysRoleModuleService.findListsByCondition(condition);

        /*未使用的权限*/
        condition.setRoleid(null);
        condition.setNtype(principal.getNtype());
        condition.setIsshare(1);
        condition.setIsdefault(1);
        condition.setState(1);
        List<SysRoleModuleDto> notUsedRoleModules = sysRoleModuleService.findListsByCondition(condition);

        /*移除已经使用的权限*/
        for (SysRoleModuleDto usedDto : usedRoleModules) {
            for (int i = 0; i < notUsedRoleModules.size(); i++) {
                SysRoleModuleDto notUsedDto = notUsedRoleModules.get(i);
                if (notUsedDto != null && usedDto.getModuleid().equals(notUsedDto.getModuleid())) {
                    notUsedRoleModules.remove(i);
                }
            }
        }

        //找回父级节点
        for (int i = 0; i < notUsedRoleModules.size(); i++) {
            SysRoleModuleDto notUsedDto = notUsedRoleModules.get(i);
            Long notModuleid = notUsedDto.getModuleid();
            Long notPModuleid = notUsedDto.getPmoduleid();

            if (!notModuleid.equals(notPModuleid)) {
                //在已使用的权限集合中，找回当前权限的父级权限
                for (SysRoleModuleDto usedDto : usedRoleModules) {
                    if (notPModuleid.equals(usedDto.getModuleid())) {
                        notUsedRoleModules.add(usedDto);
                    }
                }
            }
        }

        return WebResult.success().put("availablemodule", this.getMenus(notUsedRoleModules)).put("usedmodule", this.getMenus(usedRoleModules)).toMap();
    }

    /**
     * @return 用户所有权限
     * @Title: findAllSysModuleTrees(QuerySysRoleModuleCondition condition)
     * @Description: TODO(获取用户所有权限)
     * @author Jerry
     * @date 2016-10-17 11:02:36
     */
    @Override
    public List<Menu> findAllSysModuleTrees(QuerySysRoleModuleCondition condition) {

        List<SysRoleModuleDto> rm = sysRoleModuleService.findListsByCondition(condition);
        return getMenus(rm);
    }

    private List<Menu> getMenus(List<SysRoleModuleDto> rm) {
        Map<Long, Privilege> modules = new HashMap<Long, Privilege>();
        for (SysRoleModuleDto dto : rm) {
            Long moduleid = dto.getModuleid();
            Privilege pgforweb = privilegeService.getWebPrivileges().get(moduleid);
            if (pgforweb != null) {
                modules.put(moduleid, pgforweb);
            }

            Privilege pgforwebchat = privilegeService.getWechatPrivileges().get(moduleid);
            if (pgforwebchat != null) {
                modules.put(moduleid, pgforwebchat);
            }

            Privilege pgforapp = privilegeService.getAppPrivileges().get(moduleid);
            if (pgforapp != null) {
                modules.put(moduleid, pgforapp);
            }

            Privilege pgforoperation = privilegeService.getOperationPrivileges().get(moduleid);
            if (pgforoperation != null) {
                modules.put(moduleid, pgforoperation);
            }

        }
        return menusAppend(modules, 0L, true);
    }


    /**
     * @return 父级树节点
     * @Title: findSysModuleParentTree
     * @Description: TODO(获取一二级权限父级树节点)
     * @author Jerry Chen
     * @date 2016年9月30日 下午4:29:56
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<SysModule> findSysModuleParentTree() {
        return sysModuleDao.selectByParentTree();
    }


    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public SysModuleDto findSysModuleByCondition(QuerySysModuleCondition querySysModuleCondition) {
        return sysModuleDao.selectOneBySysModuleCondition(querySysModuleCondition);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<Long> findModuleIDbyUserID(QuerySysModuleCondition querySysModuleCondition) {
        // TODO Auto-generated method stub
        return sysModuleDao.selectModuleID(querySysModuleCondition);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public Map<Integer, List<Menu>> findAllSysModules() {
        Map<Integer, List<Menu>> SysModules = new HashMap<Integer, List<Menu>>();


        /*List<Privilege> privileges = new ArrayList<Privilege>();*/

        //获取WEB端所有权限
        Map<Long, Privilege> webModules = privilegeService.getWebPrivileges();
        /*for (Map.Entry<Long, Privilege> entry : webModules.entrySet()) {
            privileges.add(entry.getValue());
        }*/
        List<Menu> webMenus = menusAppend(webModules, 0L, true);

        //获取微信端所有权限
        Map<Long, Privilege> wechatModules = privilegeService.getWechatPrivileges();
        /*for (Map.Entry<Long, Privilege> entry : wechatModules.entrySet()) {
            privileges.add(entry.getValue());
        }*/
        List<Menu> wechatMenus = menusAppend(wechatModules, 0L, true);

        //获取APP端所有权限
        Map<Long, Privilege> appModules = privilegeService.getAppPrivileges();
        /*for (Map.Entry<Long, Privilege> entry : appModules.entrySet()) {
            privileges.add(entry.getValue());
        }*/
        List<Menu> appMenus = menusAppend(appModules, 0L, true);

        //获取操作权限
        Map<Long, Privilege> operationModules = privilegeService.getOperationPrivileges();
        List<Menu> operationMenus = new ArrayList<Menu>();
        for (Long moduleid : operationModules.keySet()) {
            Menu menu = new Menu();
            menu.setId(moduleid);
            menu.setText(operationModules.get(moduleid).getModuleName());
            operationMenus.add(menu);
        }

        SysModules.put(Constants.MODULE_TYPE_WEB, webMenus);
        SysModules.put(Constants.MODULE_TYPE_WECHAT, wechatMenus);
        SysModules.put(Constants.MODULE_TYPE_APP, appMenus);
        SysModules.put(Constants.MODULE_TYPE_OPERATION, operationMenus);

        return SysModules;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<SysModuleDto> findAllSysModules(QuerySysModuleCondition querySysModuleCondition) {
        return sysModuleDao.selectAll(querySysModuleCondition);
    }

    /**
     * @param modules  权限集合
     * @param parentid 父级ID
     * @return Menu集合
     * @Title: menusAppend(Map<Long, Privilege> modules, Long parentid)
     * @Description: TODO(追加Menu节点)
     * @author Jerry Chen
     * @date 2016年10月25日 下午6:32:37
     */
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    private List<Menu> menusAppend(Map<Long, Privilege> modules, Long parentid, boolean flag) {

        List<Menu> menus = new ArrayList<Menu>();

        Iterator<Map.Entry<Long, Privilege>> moduleIterator = modules.entrySet().iterator();
        while (moduleIterator.hasNext()) {
            Map.Entry<Long, Privilege> entry = moduleIterator.next();
            Long moduleid = entry.getKey();
            Long moduleParentid = entry.getValue().getParentID();
            if (flag) {
                if (moduleid.equals(moduleParentid)) {
                    Menu menu = new Menu(moduleid, entry.getValue().getModuleName(), entry.getValue().getUrl(), entry.getValue().getAttribute());
                    //moduleIterator.remove();
                    menu.setParent(true);
                    menu.setChildren(this.menusAppend(modules, moduleid, false));
                    menus.add(menu);
                }
            } else {
                if (!moduleid.equals(moduleParentid) && parentid.equals(moduleParentid)) {
                    Menu menu = new Menu(moduleid, entry.getValue().getModuleName(), entry.getValue().getUrl(), entry.getValue().getAttribute());
                    //moduleIterator.remove();
                    menu.setParent(false);
                    menu.setChildren(this.menusAppend(modules, moduleid, false));
                    menus.add(menu);
                }
            }

        }
        return menus;
    }


}
